#pragma once
#include <iostream>
#include <sstream>
#include <random>
#include <atomic>
#include <iomanip>
#include <fstream>
#include <ostream>
#include "Logger.hpp"

namespace chatroom{
    //标识文件唯一id
    std::string uuid(){
        std::random_device rd;//生成随机数
        std::mt19937 gmt(rd());//将rd()作为随机数种子，构造一个伪随机对象
        std::uniform_int_distribution<int> distribution(0,255);//生成一个0-255之间的数字
        std::stringstream ss;
        for(int i = 0;i < 6;i++)
        {
            ss<<std::setw(2)<<std::setfill('0')<<std::hex << distribution(gmt);
        }

        ss<<"--";
        static std::atomic<short> ready(0);
        //自动加1，之后就又从0开始
        short tmp = ready.fetch_add(1);
        ss<<std::setw(4)<<std::setfill('0')<<std::hex << tmp;
        return ss.str();
    }
    //对文件进行读取
    bool readfile(const std::string& filename,std::string& body)
    {
        //将filename中的数据放入到body当中去
        std::ifstream ifs(filename,std::ios_base::in | std::ios_base::binary);
        if(ifs.is_open() == false)
        {
            Logger_ERROR("{}文件打开失败",filename);
            return false;
        }
        //调到文件末尾方便获取文件的大小
        ifs.seekg(0,std::ios_base::end);
        size_t flen = ifs.tellg();
        //跳回文件的开始便于读取文件
        ifs.seekg(0,std::ios_base::beg);
        //将body进行扩容处理，写入文件数据
        body.resize(flen);
        //将文件数据读取到body中
        ifs.read(&body[0],flen);
        if(ifs.good()==false)
        {
            Logger_ERROR("文件读取失败");
            ifs.close();
            return false;
        }
        ifs.close();
        return true;
    }
    //验证码的随机生成
    std::string vcode()
    {
        std::random_device rd;//生成随机数
        std::mt19937 gmt(rd());//将rd()作为随机数种子，构造一个伪随机对象
        std::uniform_int_distribution<int> distribution(0,9);//生成一个0-255之间的数字
        std::stringstream ss;
        for(int i = 0;i < 4;i++)
        {
            ss<< distribution(gmt);
        }
        return ss.str();
    }
    //对文件进行写入
    bool writefile(const std::string& filename,const std::string& body)
    {
        //将body中的数据输出到文件中
        std::ofstream ofs(filename,std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
        if(ofs.is_open() == false)
        {
            Logger_ERROR("{}文件打开失败",filename);
            return false;
        }
        ofs.write(body.c_str(),body.size());
        if(ofs.good()==false)
        {
            Logger_ERROR("文件写入失败");
            ofs.close();
            return false;
        }
        ofs.close();
        return true;
    }
}